#!/ur/bin/python
#coding=utf-8

import rados
import sys
import web
import json
#import threadpool
import threading
import random
import copy
import logging
import logging.config

from ceph_mon_md import *
from ceph_osd_md import *
from ceph_config_md import *
from ceph_diskusage_md import *
from ceph_data_md import *
from ceph_scrub_md import *
from ceph_image_md import *
from ceph_disk_md import *
from ceph_update_md import *
from command import *
from global_list import *

#结果字典，key为reqid
results={}

urls = (
    '/ceph/mon', 'mon',
    '/ceph/osd', 'osd',
    '/ceph/config', 'config',
    '/ceph/diskusage', 'diskusage',
    '/ceph/data', 'data',
    '/ceph/scrub', 'scrub',
    '/ceph/disk', 'disk',
    '/ceph/image', 'image',
    '/ceph/update', 'update',
    '/ceph/result', 'result',
)

#各个class动作名称一览
MonAct = ('getstats','getstatsbyregex','start','stop','restart','delete','add')
OsdAct = ('getstats','getstatsbyregex','start','stop','restart','getreweight','setreweight',\
        'getnearfull','setnearfull','getfull','setfull','setout')
ConfigAct = ('getcommonlist','getlistbyregex','setval2file','setval2temp')
DiskusgAct = ('getstats','setnearfull','setfull')
DataAct = ('getstats','enable','disable')
ScrubAct = ('getstats','on','off','notdone','dodeepscrub','doscrub')
DiskAct = ('getinfo','checkdisk','replacedata','replacejournal')
ImageAct = ('getpoolname','getallstats','getstats','getstatsbyregex','getblklist','delblklist')
UpdateAct = ('getstats','getdest','doupdate')

app = web.application(urls, globals())

#处理mon相关请求
class mon:
    def GET(self):
	user_data=web.input(act='None',val='None',host='None')
        #检验act参数是否正确
        if user_data.act not in MonAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("mon")
        MonClt=ReqMon(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=MonClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='mon'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理osd相关请求
class osd:
    def GET(self):
        user_data=web.input(act='None',page=0,pagesize=0,val='None',item='None',host='None')
        #检验act参数是否正确
        if user_data.act not in OsdAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("osd")
        OsdClt=ReqOsd(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=OsdClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='osd'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理集群配置参数相关设置请求
class config:
    def GET(self):
        user_data=web.input(act='None',page=0,pagesize=0,val='None',item='None')
        #检验act参数是否正确
        if user_data.act not in ConfigAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("config")
        ConfigClt=ReqConfig(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=ConfigClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='config'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理集群容量状态相关请求
class diskusage:
    def GET(self):
        user_data=web.input(act='None',val='None')
        #检验act参数是否正确
        if user_data.act not in DiskusgAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("diskusage")
        DiskusgClt=ReqDiskusg(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=DiskusgClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='diskusage'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理集群数据恢复/回填/均衡相关设置请求
class data:
    def GET(self):
        user_data=web.input(act='None',item='None')
        #检验act参数是否正确
        if user_data.act not in DataAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("data")
        DataClt=ReqData(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=DataClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='data'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理集群scrub/deep-scrub相关操作请求
class scrub:
    def GET(self):
        user_data=web.input(act='None',page=0,pagesize=0,val='None',item='None')
        #检验act参数是否正确
        if user_data.act not in ScrubAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("scrub")
        ScrubClt=ReqScrub(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=ScrubClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='consistent'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理集群更换磁盘相关请求
class disk:
    def GET(self):
        user_data=web.input(act='None',cat='None',host='None',sn='None',item='None')
        #检验act参数是否正确
        if user_data.act not in DiskAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("disk")
        DiskClt=ReqDisk(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=DiskClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='disk'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理集群image相关信息请求
class image:
    def GET(self):
        user_data=web.input(act='None',page=0,pagesize=0,val='None',item='None',pool='None')
        #检验act参数是否正确
        if user_data.act not in ImageAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("image")
        ImageClt=ReqImage(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=ImageClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='image'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#处理集群升级相关请求
class update:
    def GET(self):
        user_data=web.input(act='None',page=0,pagesize=0,host='None',ver='0.0.0')
        #检验act参数是否正确
        if user_data.act not in UpdateAct:
            return 'error'
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        while True:
            #生成reqid
            reqid=random.randint(100,10000000)
            if True == res.has_key(reqid):
                continue
            else:
                break
        mtx.release()
        handle=global_list.get_value('HANDLE')
        logger = logging.getLogger("update")
        UpdateClt=ReqUpdate(handle,dict(user_data),reqid,logger)
        t=threading.Thread(target=UpdateClt.ThreadDealer)
        t.setDaemon(True)
        t.start()
        resdict=dict()
        resdict['act']=user_data.act
        resdict['type']='update'
        resdict['status']='ok'
        resdict['reqid']=reqid
        return json.dumps(resdict)

#根据以上各个请求，输出状态
class result:
    def GET(self):
        user_data=web.input(reqid=0,act='None',type='None',page=0,pagesize=0,sn='0')
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        if True == res.has_key(int(user_data.reqid)):
            if user_data.act=='replacedata' or user_data.act=='replacejournal':
                if user_data.sn != '0':
                    res[int(user_data.reqid)]['sn']=copy.deepcopy(user_data.sn)
            ret=json.dumps(res[int(user_data.reqid)])
            del res[int(user_data.reqid)]
        else:
            ret='None'
        mtx.release()
        return ret

if __name__ == "__main__":
    try:
        #配置日志
        logging.config.fileConfig('logging.conf')
    except Exception as e:
        print 'config logging failed, error is '+e
        sys.exit("ceph_main_md.py error, exit...")

    try:
        #读取配置文件
        config=ConfigParser.ConfigParser()
        with open("./config","r") as cfgfile:
            config.readfp(cfgfile)
            conf_file=config.get("base","conffile")
            key_ring=config.get("base","keyring")
            deploy_path=config.get("base","deploypath")
    except Exception as e:
        print 'read config file failed, error is '+e
        sys.exit("ceph_main_md.py error, exit...")
    else:
        print 'conffile='+str(conf_file)+',keyring='+str(key_ring)+',deploypath='+str(deploy_path)

    global_list._init()
    #链接Ceph集群
    try:
        cluster=rados.Rados(conffile=conf_file,conf=dict(keyring=key_ring))
        cluster.connect()
    except Exception as e:
        print 'connect ceph cluster failed, error is '+e
        sys.exit("ceph_main_md.py error, exit...")
    else:
        print "\nCluster ID: " + cluster.get_fsid()
        print 'main cluster '+str(cluster)

    mutex=threading.Lock()
    global_list.set_value('HANDLE',cluster)
    global_list.set_value('MUTEX',mutex)
    global_list.set_value('RESULTS',results)
    #cluster.shutdown()
    app.run()
